package com.franklin.java.api.psi.data.resolver;

import com.franklin.plugins.common.collection.PrettyArrayList;
import com.franklin.java.api.psi.data.PsiData;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author Franklin
 * @since 2021/08/15/ 21:24
 */
public class MethodBodyResolver implements PsiDataResolver {


    @Override
    public PsiData resolve(String name, String value, PsiElement dataElement) {
        PsiMethod psiMethod = PsiTreeUtil.getParentOfType(dataElement, PsiMethod.class);
        if (Objects.nonNull(psiMethod)) {
            //从PsiMethod里找
            PsiCodeBlock psiMethodBody = psiMethod.getBody();
            if (Objects.nonNull(psiMethodBody)) {
                String[] lines = psiMethodBody.getText().split("\n");
                int length = 0;
                List<PsiDeclarationStatement> declarationStatementList = new PrettyArrayList<>();
                for (String line : lines) {
                    if (line.trim().startsWith("/")){
                        length = length + line.length() + 1;
                        continue;
                    }
                    PsiElement elementAt = psiMethodBody.findElementAt(length + line.length() / 2);
                    if (Objects.nonNull(elementAt)){
                        PsiDeclarationStatement statement = PsiTreeUtil.getParentOfType(elementAt, PsiDeclarationStatement.class);
                        if (Objects.nonNull(statement)){
                            declarationStatementList.add(statement);
                        }
                    }
                    length = length + line.length() + 1;
                }
                List<PsiDeclarationStatement> psiDeclarationStatementList = declarationStatementList
                        .stream()
                        .filter(psiDeclarationStatement -> {
                            PsiElement[] declaredElements = psiDeclarationStatement.getDeclaredElements();
                            for (PsiElement declaredElement : declaredElements) {
                                if (declaredElement instanceof PsiLocalVariable){
                                    PsiLocalVariable psiLocalVariable = (PsiLocalVariable) declaredElement;
                                    if (psiLocalVariable.getName().equals(name)){
                                        return true;
                                    }
                                }
                            }
                            return false;
                        })
                        .collect(Collectors.toList());
                PsiData psiData = resolveVariable(dataElement, value, psiDeclarationStatementList);
                if (Objects.nonNull(psiData)){
                    return psiData;
                }
                //子代码块
            }
        }
        return null;
    }


}
